#include <Lucnx/types.h>
#include <Lucnx/syscall.h>

static u32 syscall0(u32 nr)
{
    u32 ret;
    asm volatile
    (
        "int $0x80\n"
        : "=a"(ret)
        : "a"(nr)
    );
    return ret;
}

static u32 syscall1(u32 nr, u32 arg1)
{
    u32 ret;
    asm volatile
    (
        "int $0x80\n"
        : "=a"(ret)
        : "a"(nr), "b"(arg1)
    );
    return ret;
}

static u32 syscall2(u32 nr, u32 arg1, u32 arg2)
{
    u32 ret;
    asm volatile
    (
        "int $0x80\n"
        : "=a"(ret)
        : "a"(nr), "b"(arg1), "c"(arg2)
    );
    return ret;
}

static u32 syscall3(u32 nr, u32 arg1, u32 arg2, u32 arg3)
{
    u32 ret;
    asm volatile
    (
        "int $0x80\n"
        : "=a"(ret)
        : "a"(nr), "b"(arg1), "c"(arg2), "d"(arg3)
    );
    return ret;
}

void putchar(char ch)
{
    write(stdout, &ch, 1);
}

size_t write(fd_t fd, char *buf, int nr)
{
    return syscall3(SYS_NR_WRITE, fd, buf, nr);
}

void clear()
{
    syscall0(SYS_NR_CLEAR);
}

size_t read(fd_t fd, char *buf, int nr)
{
    return syscall3(SYS_NR_READ, fd, buf, nr);
}

pid_t getpid()
{
    return (pid_t) syscall0(SYS_NR_GETPID);
}

void sleep(u32 ms)
{
    return syscall1(SYS_NR_SLEEP, ms);
}

size_t sysinfo(int nr, void *buf)
{
    return syscall2(SYS_NR_SYSINFO, nr, buf);
}

void exit()
{
    syscall0(SYS_NR_EXIT);
}

int brk(void *brk)
{
    return (int) syscall1(SYS_NR_BRK, brk);
}

pid_t fork()
{
    return (pid_t) syscall0(SYS_NR_FORK);
}

pid_t getppid()
{
    return (pid_t) syscall0(SYS_NR_GETPPID);
}